package com.keba.lamp.office.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.keba.basic.annotation.log.WebLog;
import com.keba.basic.base.R;
import com.keba.basic.context.ContextConstants;
import com.keba.basic.context.ContextUtil;
import com.keba.lamp.office.exception.ExceptionCodeEnum;
import com.keba.lamp.office.properties.WebOfficeProperties;
import com.keba.lamp.office.service.OfficeApiFacade;
import com.keba.lamp.office.vo.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/anyTenant/office")
public class OfficeController {
    private final WebOfficeProperties officeProperties;

    private final OfficeApiFacade officeApiFacade;


    /**
     * 初始化
     *
     * @return
     */
    @PostMapping("/init")
    @WebLog("标准模版初始化")
    public R<OfficeInitVO> init(@RequestBody @Validated OfficeQueryVO queryVO) {
        return R.success(officeApiFacade.initOffice(queryVO));
    }

    /**
     * 初始化
     *
     * @return
     */
    @PostMapping("/caseTemplate/init")
    @WebLog("案件模版初始化")
    public R<OfficeInitVO> initCaseTemplate(@RequestBody @Validated OfficeQueryVO queryVO) {
        return R.success(officeApiFacade.initOffice(queryVO));
    }

    /**
     * /v3/3rd/files/
     */
    @GetMapping("/v3/3rd/files/{file_id}")
    @WebLog("获取文件信息")
    public R<OfficeFileVO> getFileId(@PathVariable("file_id") String file_id, HttpServletRequest request) {
        log.info("==获取文件信息:file_id:{}", file_id);
        String userQuery = request.getHeader("X-User-Query");
        String appId = request.getHeader("X-App-ID");
        log.info("====获取文件信息返回头信息：userQuery:{},appId:{}", userQuery, appId);
        request.getParameterMap().forEach((k, v) -> {
            log.info("====获取文件信息参数信息：k:{},v:{}", k, JSONUtil.toJsonStr(v));
        });
        return R.success(officeApiFacade.getOffice(file_id));
    }

    /**
     * /v3/3rd/files/:file_id/download
     */
    @GetMapping("/v3/3rd/files/{file_id}/download")
    @WebLog("获取office文件URL")
    public R<OfficeFileDownloadVO> download(@PathVariable("file_id") String file_id) {
        return R.success(officeApiFacade.download(file_id));
    }

    /**
     * /v3/3rd/users?user_ids=1&user_ids=2&user_ids=3
     */
    @GetMapping("/v3/3rd/users")
    @WebLog("获取用户信息")
    public R<List<OfficeUserVO>> getUser(@RequestParam("user_ids") List<Long> userId) {
        return R.success(officeApiFacade.getUser(userId));
    }

    /**
     * /v3/3rd/files/:file_id/permission
     */
    @GetMapping("/v3/3rd/files/{file_id}/permission")
    @WebLog("获取文件权限信息")
    public R<OfficePermissionVO> getPermission(@PathVariable("file_id") String file_id) {
        return R.success(officeApiFacade.getPermission(Convert.toLong(file_id)));
    }

    /**
     * /v3/3rd/files/:file_id/upload/prepare
     */
    @GetMapping("/v3/3rd/files/{file_id}/upload/prepare")
    @WebLog("office上传文件准备")
    public R<OfficeUploadPrepareVO> uploadPrepare(@PathVariable("file_id") String file_id) {
        return R.success(OfficeUploadPrepareVO.builder().digest_types(new String[]{"md5"}).build());
    }

    /**
     * /v3/3rd/files/:file_id/upload/address
     *
     * @return
     */
    @PostMapping("/v3/3rd/files/{file_id}/upload/address")
    @WebLog
    public R<Map<String, Object>> uploadAddress(@PathVariable("file_id") String file_id, @RequestBody OfficeUploadAddressVO uploadAddressVO, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        Map<String, String> headers = new HashMap<>();
        headers.put("fileId", file_id);
        headers.put("fileName", URLEncoder.encode(uploadAddressVO.getName(), Charset.defaultCharset()));
        headers.put("fileSize", Convert.toStr(uploadAddressVO.getSize()));
        headers.put(ContextConstants.USER_ID_HEADER, ContextUtil.getUserId().toString());
        headers.put(ContextConstants.TENANT_ID_KEY, ContextUtil.getTenantId().toString());
        map.put("method", "PUT");
        map.put("headers", headers);
        map.put("url", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/anyTenant/v3/3rd/files/upload");
        log.info("==获取office上传地址:file_id:{},返回信息：{}", file_id, JSONUtil.toJsonStr(map));
        return R.success(map);

    }

    /**
     * /v3/3rd/files/:file_id/upload/complete
     * file_id	Path	是	string	文档 ID
     * request	Body	是	Object	获取上传地址时相同的请求
     * name	Request	是	string	文档名称
     * size	Request	是	integer	文档大小，单位 byte
     * digest	Request	是	map<string, string>	文档校验和，key 为算法，value 为结果值
     * is_manual	Request	是	boolean	是否手动保存，即用户手动 ctrl/cmd + s 或点击保存版本触发的保存，区别于定时触发的自动保存
     * attachment_size	Request	否	integer	文档内包含的附件的大小，单位 byte
     * content_type	Request	否	string	文档的 MIME 类型
     * response	Body	是	Object	上传文档完成后，存储服务返回的 HTTP Response
     * status_code	Response	是	integer	上传文档时，存储服务返回的 HTTP Response Status
     * headers	Response	否	map<string, string>	上传文档时，存储服务返回的 HTTP Response Header
     * body	Response	否	[]byte	上传文档时，存储服务返回的 HTTP Response Body 的 base64 编码
     * send_back_params	Body	否	map<string, string>	获取上传地址时，要求原样带回的额外参数
     */
    @PostMapping("/v3/3rd/files/{file_id}/upload/complete")
    @WebLog
    public R<OfficeFileVO> uploadComplete(@PathVariable("file_id") String file_id, @RequestBody OfficeUploadCompleteVO completeVO) {
        log.info("Office 文件id:{},上传文件后回调信息: {}", file_id, JSONUtil.toJsonStr(completeVO));
        return R.success(officeApiFacade.getOffice(file_id));
    }

}
